<template>
  <div>
    <div class="header">
      <span class="process">{{ resultMsg }}</span>
      <span class="key">{{ firstNum || lastNum }}</span>
    </div>
    <div class="body">
      <div class="row row-1">
        <button order="percentage">%</button>
        <button class="btn-danger" order="clear">CE</button>
        <button class="btn-danger" order="clear">C</button>
        <button order="del">
          <i class="el-icon-back"></i>
        </button>
      </div>
      <div class="row row-1">
        <button order="1/x">1/x</button>
        <button order="x²">x²</button>
        <button order="2/x">2/x</button>
        <button order="div">÷</button>
      </div>
      <div class="row">
        <button order="7">7</button>
        <button order="8">8</button>
        <button order="9">9</button>
        <button order="mult">×</button>
      </div>
      <div class="row">
        <button order="4">4</button>
        <button order="5">5</button>
        <button order="6">6</button>
        <button order="min">－</button>
      </div>
      <div class="row">
        <button order="1">1</button>
        <button order="2">2</button>
        <button order="3">3</button>
        <button order="add">＋</button>
      </div>
      <div class="row">
        <button order="+/-">+/-</button>
        <button order="0">0</button>
        <button order=".">.</button>
        <button class="btn-equal" order="equal">=</button>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      enterMathFlag: false,
      resultMsg: '', // 计算器显示
      firstNum: '', // 计算方式的前参  后参
      lastNum: '', // 计算方式的前参  后参
      mathStart: false, // 计算开始结束标识
      mathfun: '', // 计算方式标识
    }
  },
  computed: {},
  watch: {},
  mounted() {
    const _this = this
    document.addEventListener('keydown', _this.watchKeydown)
    // 所有按钮
    const btns = document.getElementsByTagName('button')
    // 1. 对于数字和运算符按钮，点击后填充算式：
    for (const btn of btns) {
      btn.addEventListener('click', function () {
        const child = this.getAttribute('order')
        if (isNaN(Number(child))) {
          _this.mathAction(child)
        } else {
          _this.numBtn(Number(child))
        }
      })
    }
  },
  methods: {
    watchKeydown(e) {
      const keyNum = window.event ? e.keyCode : e.which // 获取被按下的键值
      console.log(keyNum)
      this.btnSwitch(keyNum)
    },
    numBtn(val) {
      const _this = this
      _this.playAudio()

      if (_this.enterMathFlag && !_this.mathStart) {
        _this.enterMathFlag = false
        _this.resetCalculation()
      }

      if (_this.mathfun === 'div' && _this.lastNum === '' && val === 0) {
        return
      }

      if (_this.mathStart) {
        if (_this.lastNum.indexOf('.') > 0 && val === '.') {
          return
        }

        if (_this.lastNum.length > 11) {
          return
        }

        if (_this.lastNum === '0' && val === '0') {
          return
        }

        if (val === '.' && _this.lastNum === '') {
          val = '0.'
        }

        _this.lastNum += val
      } else {
        if (_this.firstNum.indexOf('.') > 0 && val === '.') {
          return
        }

        if (_this.firstNum.length > 11) {
          return
        }

        if (_this.firstNum === '0' && val === '0') {
          return
        }

        if (val === '.' && _this.firstNum === '') {
          val = '0.'
        }
        _this.firstNum += val
      }

      _this.resultMsg += val
    },
    resetCalculation() {
      const _this = this
      _this.mathStart = false
      _this.resultMsg = ''
      _this.firstNum = ''
      _this.lastNum = ''
      _this.mathfun = ''
    },
    btnSwitch(key) {
      const data = {
        8: () => this.mathAction('del'),
        13: () => this.mathAction('equal'),
        27: () => this.mathAction('clear'),
        53: () => this.mathAction('percentage'),
        96: () => this.numBtn(0),
        97: () => this.numBtn(1),
        98: () => this.numBtn(2),
        99: () => this.numBtn(3),
        100: () => this.numBtn(4),
        101: () => this.numBtn(5),
        102: () => this.numBtn(6),
        103: () => this.numBtn(7),
        104: () => this.numBtn(8),
        105: () => this.numBtn(9),
        110: () => this.numBtn('.'),
        107: () => this.mathAction('add'),
        109: () => this.mathAction('min'),
        106: () => this.mathAction('mult'),
        111: () => this.mathAction('div'),
      }
      data[key] && data[key]()
    },
    mathAction(val) {
      const _this = this
      _this.playAudio()
      if (val === 'clear') {
        _this.enterMathFlag = false
        _this.resetCalculation()
      }
      if (_this.firstNum === '') {
        return false
      }
      switch (val) {
        case 'del':
          if (_this.mathStart) {
            if (_this.lastNum !== '') {
              _this.lastNum = _this.DeleteLastCharacter(_this.lastNum)
            } else {
              _this.mathfun = ''
              _this.mathStart = false
            }
          } else {
            _this.firstNum = _this.DeleteLastCharacter(_this.firstNum)
          }
          _this.resultMsg = _this.DeleteLastCharacter(_this.resultMsg)
          break
        case 'percentage':
          _this.resultMsg =
            parseFloat(
              (
                ((parseFloat(_this.firstNum) / 100) * 1).toFixed(10) + ''
              ).replace(/(0+)$/g, '')
            ) + ''
          _this.firstNum = _this.resultMsg
          _this.lastNum = ''
          _this.mathfun = ''
          break

        case 'add':
          _this.restorePreconditions(function () {
            _this.resultMsg += '+'
            _this.mathfun = 'add'
          })
          break
        case 'min':
          _this.restorePreconditions(function () {
            _this.resultMsg += '-'
            _this.mathfun = 'min'
          })
          break
        case 'mult':
          _this.restorePreconditions(function () {
            _this.resultMsg += '×'
            _this.mathfun = 'mult'
          })
          break
        case 'div':
          _this.restorePreconditions(function () {
            _this.resultMsg += '÷'
            _this.mathfun = 'div'
          })
          break
        case 'equal':
          _this.equal(_this.mathfun)
          break
      }
    },
    equal(key) {
      const _this = this
      if (_this.lastNum === '') {
        _this.laseNum = '1'
        _this.mathStart = false
        _this.resultMsg =
          parseFloat((parseFloat(_this.firstNum) * 1).toFixed(10) + '') + ''
        _this.firstNum = _this.resultMsg
        _this.lastNum = ''
        _this.mathfun = ''
        return
      }
      switch (key) {
        case 'add':
          _this.mathStart = false
          _this.resultMsg =
            parseFloat(
              (parseFloat(_this.firstNum) + parseFloat(_this.lastNum)).toFixed(
                10
              )
            ) + ''
          _this.CheckResultMaxLength(_this.resultMsg)
          break

        case 'min':
          _this.mathStart = false
          _this.resultMsg =
            parseFloat(
              (parseFloat(_this.firstNum) - parseFloat(_this.lastNum)).toFixed(
                10
              )
            ) + ''
          _this.CheckResultMaxLength(_this.resultMsg)
          break

        case 'mult':
          _this.mathStart = false
          _this.resultMsg =
            parseFloat(
              (parseFloat(_this.firstNum) * parseFloat(_this.lastNum)).toFixed(
                10
              )
            ) + ''
          _this.CheckResultMaxLength(_this.resultMsg)

          break

        case 'div':
          if (parseFloat(_this.lastNum) === 0) {
            return
          }
          _this.mathStart = false
          _this.resultMsg =
            parseFloat(
              (parseFloat(_this.firstNum) / parseFloat(_this.lastNum)).toFixed(
                10
              )
            ) + ''
          _this.CheckResultMaxLength(_this.resultMsg)
          break
      }
    },
    /**
     * 检查最大位数显示
     */
    CheckResultMaxLength(result) {
      const _this = this
      _this.firstNum = result
      _this.lastNum = ''
      _this.mathfun = ''
    },
    /**
     * 删除最后一位字符
     */
    DeleteLastCharacter(value) {
      return value.substr(0, value.length - 1)
    },
    /**
     * 整理上一次的结果/优化显示效果
     */
    restorePreconditions(callback) {
      const _this = this
      _this.firstNum = parseFloat(_this.firstNum) + ''
      _this.resultMsg = _this.firstNum
      if (_this.mathfun) {
        _this.equal(_this.mathfun)
      }
      _this.mathStart = true

      if (_this.mathfun !== '') {
        return
      }
      callback()
    },
    playAudio() {
      const audio = new Audio()
      audio.src = './assets/file/audio.mp3'
      audio.play()
    },
  },
}
</script>
<style lang="scss" scoped>
@import '@/assets/css/theme.scss';
.header {
  display: flex;
  flex-direction: column;
  padding: 10px;
  height: 100px;
  box-sizing: border-box;
  & > span {
    text-align: right;
  }
  & > .process {
    height: 20px;
  }
  & > .key {
    margin-top: 10px;
    font-size: $fz-30;
    font-weight: 700;
  }
}

.row {
  display: flex;
  column-count: 4;
  margin-left: -10px;
  button {
    padding: 20px;
    flex: 1;
    font-size: $fz-16;
    border: 1px solid #ddd;
    background: $bg-color-primary;
    margin-left: 10px;
    margin-top: 10px;
    color: $fz-color-white;
    cursor: pointer;
    &:hover {
      box-shadow: 0 0 10px 5px $bg-color-primary;
    }
  }
  &:not(.row-1) {
    button {
      &:last-child {
        background-color: $bg-color-default;
        &:hover {
          box-shadow: 0 0 10px 5px $bg-color-default;
        }
      }
    }
  }
  .btn-equal {
    font-size: $fz-18;
    background-color: $bg-color-confirm !important;
    &:hover {
      box-shadow: 0 0 10px 5px $bg-color-confirm !important;
    }
  }
  .btn-danger {
    background-color: $bg-color-danger !important;
    &:hover {
      box-shadow: 0 0 10px 5px $bg-color-danger !important;
    }
  }
}
.row-1 {
  button {
    background-color: $bg-color-default;
    &:hover {
      box-shadow: 0 0 10px 5px $bg-color-default;
    }
  }
}
</style>